const ROWS = 20;
const COLS = 10;
const BLOCK_SIZE = 30;
const SHAPES = [
    [[1, 1, 1, 1]], // I
    [[1, 1, 1], [0, 1, 0]], // T
    [[1, 1], [1, 1]], // O
    [[1, 1, 0], [0, 1, 1]], // Z
    [[0, 1, 1], [1, 1, 0]], // S
    [[1, 1, 1], [1, 0, 0]], // L
    [[1, 1, 1], [0, 0, 1]]  // J
];

const COLORS = ['#1abc9c', '#3498db', '#9b59b6', '#e67e22', '#e74c3c', '#2ecc71', '#f1c40f'];

class Tetris {
    constructor() {
        this.board = Array.from({length: ROWS}, () => Array(COLS).fill(0));
        this.currentPiece = this.randomPiece();
        this.nextPiece = this.randomPiece();
        this.score = 0;
        this.level = 1;
        this.isGameOver = false;
        this.isPaused = false;
        this.dropInterval = 1000;
        this.lastDrop = Date.now();
        this.init();
    }

    init() {
        this.createBoard();
        this.setupControls();
        this.updateInfo();
        this.gameLoop();
    }

    createBoard() {
        const board = document.querySelector('.game-board');
        board.innerHTML = '';
        for (let row = 0; row < ROWS; row++) {
            for (let col = 0; col < COLS; col++) {
                const cell = document.createElement('div');
                cell.classList.add('cell');
                cell.style.width = `${BLOCK_SIZE}px`;
                cell.style.height = `${BLOCK_SIZE}px`;
                board.appendChild(cell);
            }
        }
    }

    randomPiece() {
        const index = Math.floor(Math.random() * SHAPES.length);
        return {
            shape: SHAPES[index],
            color: COLORS[index],
            x: Math.floor(COLS / 2) - 1,
            y: 0
        };
    }

    drawPiece(piece) {
        piece.shape.forEach((row, i) => {
            row.forEach((value, j) => {
                if (value) {
                    const x = piece.x + j;
                    const y = piece.y + i;
                    if (y >= 0 && y < ROWS && x >= 0 && x < COLS) {
                        const index = y * COLS + x;
                        const cell = document.querySelector(`.game-board .cell:nth-child(${index + 1})`);
                        cell.style.backgroundColor = piece.color;
                    }
                }
            });
        });
    }

    clearPiece(piece) {
        piece.shape.forEach((row, i) => {
            row.forEach((value, j) => {
                if (value) {
                    const x = piece.x + j;
                    const y = piece.y + i;
                    if (y >= 0 && y < ROWS && x >= 0 && x < COLS) {
                        const index = y * COLS + x;
                        const cell = document.querySelector(`.game-board .cell:nth-child(${index + 1})`);
                        cell.style.backgroundColor = '#2c3e50';
                    }
                }
            });
        });
    }

    isValidMove(piece, x = 0, y = 0) {
        return piece.shape.every((row, i) => {
            return row.every((value, j) => {
                if (!value) return true;
                const newX = piece.x + j + x;
                const newY = piece.y + i + y;
                return newX >= 0 && newX < COLS && newY < ROWS && 
                    (newY < 0 || !this.board[newY][newX]);
            });
        });
    }

    lockPiece() {
        this.currentPiece.shape.forEach((row, i) => {
            row.forEach((value, j) => {
                if (value) {
                    const x = this.currentPiece.x + j;
                    const y = this.currentPiece.y + i;
                    if (y >= 0) {
                        this.board[y][x] = this.currentPiece.color;
                    }
                }
            });
        });
        this.clearLines();
        if (this.isGameOver) return;
        this.currentPiece = this.nextPiece;
        this.nextPiece = this.randomPiece();
        this.updateNextPiece();
        if (!this.isValidMove(this.currentPiece)) {
            this.gameOver();
        }
    }

    clearLines() {
        let linesCleared = 0;
        for (let row = ROWS - 1; row >= 0; row--) {
            if (this.board[row].every(cell => cell !== 0)) {
                this.board.splice(row, 1);
                this.board.unshift(Array(COLS).fill(0));
                linesCleared++;
                row++;
            }
        }
        if (linesCleared > 0) {
            this.score += linesCleared * 100 * this.level;
            this.level = Math.floor(this.score / 1000) + 1;
            this.dropInterval = Math.max(100, 1000 - (this.level - 1) * 100);
            this.updateInfo();
        }
    }

    updateInfo() {
        document.querySelector('.score-display').textContent = `Score: ${this.score}`;
        document.querySelector('.level-display').textContent = `Level: ${this.level}`;
    }

    updateNextPiece() {
        const nextPieceContainer = document.querySelector('.next-piece');
        nextPieceContainer.innerHTML = '';
        this.nextPiece.shape.forEach((row, i) => {
            row.forEach((value, j) => {
                const cell = document.createElement('div');
                cell.classList.add('cell');
                cell.style.width = `${BLOCK_SIZE}px`;
                cell.style.height = `${BLOCK_SIZE}px`;
                cell.style.backgroundColor = value ? this.nextPiece.color : '#2c3e50';
                nextPieceContainer.appendChild(cell);
            });
        });
    }

    gameOver() {
        this.isGameOver = true;
        document.querySelector('.game-over').style.display = 'block';
    }

    setupControls() {
        document.addEventListener('keydown', (e) => {
            if (this.isGameOver || this.isPaused) return;
            switch (e.code) {
                case 'ArrowLeft':
                    if (this.isValidMove(this.currentPiece, -1)) {
                        this.clearPiece(this.currentPiece);
                        this.currentPiece.x--;
                        this.drawPiece(this.currentPiece);
                    }
                    break;
                case 'ArrowRight':
                    if (this.isValidMove(this.currentPiece, 1)) {
                        this.clearPiece(this.currentPiece);
                        this.currentPiece.x++;
                        this.drawPiece(this.currentPiece);
                    }
                    break;
                case 'ArrowDown':
                    if (this.isValidMove(this.currentPiece, 0, 1)) {
                        this.clearPiece(this.currentPiece);
                        this.currentPiece.y++;
                        this.drawPiece(this.currentPiece);
                    }
                    break;
                case 'ArrowUp':
                    this.rotatePiece();
                    break;
                case 'Space':
                    this.hardDrop();
                    break;
            }
        });

        document.querySelector('.start-button').addEventListener('click', () => {
            this.resetGame();
        });

        document.querySelector('.game-over button').addEventListener('click', () => {
            this.resetGame();
        });
    }

    rotatePiece() {
        const rotated = this.currentPiece.shape[0].map((_, i) =>
            this.currentPiece.shape.map(row => row[i]).reverse()
        );
        const originalShape = this.currentPiece.shape;
        this.currentPiece.shape = rotated;
        if (!this.isValidMove(this.currentPiece)) {
            this.currentPiece.shape = originalShape;
        } else {
            this.clearPiece(this.currentPiece);
            this.drawPiece(this.currentPiece);
        }
    }

    hardDrop() {
        while (this.isValidMove(this.currentPiece, 0, 1)) {
            this.clearPiece(this.currentPiece);
            this.currentPiece.y++;
        }
        this.drawPiece(this.currentPiece);
        this.lockPiece();
    }

    resetGame() {
        this.board = Array.from({length: ROWS}, () => Array(COLS).fill(0));
        this.currentPiece = this.randomPiece();
        this.nextPiece = this.randomPiece();
        this.score = 0;
        this.level = 1;
        this.isGameOver = false;
        this.isPaused = false;
        this.dropInterval = 1000;
        this.lastDrop = Date.now();
        this.updateInfo();
        this.updateNextPiece();
        document.querySelector('.game-over').style.display = 'none';
        this.createBoard();
    }

    gameLoop() {
        if (this.isGameOver || this.isPaused) {
            requestAnimationFrame(() => this.gameLoop());
            return;
        }

        const now = Date.now();
        if (now - this.lastDrop > this.dropInterval) {
            if (this.isValidMove(this.currentPiece, 0, 1)) {
                this.clearPiece(this.currentPiece);
                this.currentPiece.y++;
                this.drawPiece(this.currentPiece);
            } else {
                this.lockPiece();
            }
            this.lastDrop = now;
        }

        this.drawBoard();
        requestAnimationFrame(() => this.gameLoop());
    }

    drawBoard() {
        this.board.forEach((row, i) => {
            row.forEach((cell, j) => {
                const index = i * COLS + j;
                const cellElement = document.querySelector(`.game-board .cell:nth-child(${index + 1})`);
                cellElement.style.backgroundColor = cell || '#2c3e50';
            });
        });
        this.drawPiece(this.currentPiece);
    }
}

new Tetris();
